package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.media.MediaConstans;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.media.dto.NewsDto;
import com.heima.model.media.dto.WmNewsDto;
import com.heima.model.media.dto.WmNewsPageReqDto;
import com.heima.model.media.pojos.WmMaterial;
import com.heima.model.media.pojos.WmNews;
import com.heima.model.media.pojos.WmUser;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.utils.threadlocal.WmThreadLocalUtils;
import com.heima.wemedia.feign.ArticleFeign;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.service.WmMaterialService;
import com.heima.wemedia.service.WmNewsMaterialService;
import com.heima.wemedia.service.WmNewsService;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {


    /**
     * 分页条件查询
     * @param dto
     * @return
     */
    @Override
    public ResponseResult<List<WmNews>> findAll(WmNewsPageReqDto dto) {
        //检查参数
        if (dto==null){
            dto=new WmNewsPageReqDto();
        }
        dto.checkParam();

       /* private Short status;//状态
        private Date beginPubdate;//开始时间
        private Date endPubdate;//结束时间
        private Integer channelId;//所属频道ID
        private String keyWord;//关键字*/
        //分页条件查询
        LambdaQueryWrapper<WmNews> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(dto.getStatus()!=null,WmNews::getStatus,dto.getStatus());
        wrapper.eq(dto.getChannelId()!=null,WmNews::getChannelId,dto.getChannelId());
        wrapper.ge(dto.getBeginPubdate()!=null,WmNews::getSubmitedTime,dto.getBeginPubdate());
        wrapper.le(dto.getEndPubdate()!=null,WmNews::getSubmitedTime,dto.getEndPubdate());
        wrapper.like(StringUtils.isNoneBlank(dto.getKeyWord()),WmNews::getTitle,dto.getKeyWord());
        wrapper.orderByDesc(WmNews::getCreatedTime);
        Page<WmNews> page=new Page<>(dto.getPage(),dto.getSize());
        IPage<WmNews> page1 = page(page, wrapper);
        PageResponseResult result=new PageResponseResult((int) page1.getCurrent(),(int)page1.getSize(),(int)page1.getTotal());
       result.setData(page1.getRecords());
        return result;
    }

    @Value("${fdfs.url}")
    String fileServerUrl;
    @Autowired
    WmNewsMaterialService wmNewsMaterialService;

    @Autowired
    WmMaterialService wmMaterialService;
    /**
     * 自媒体文章-删除
     * @param id
     * @return
     */
    @Override
    public ResponseResult delete(Integer id) {
        //检查数据
        if (id==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //查询数据库，判断是否能删除
        WmNews wmNews = getById(id);
        if (wmNews==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        if (wmNews.getEnable()==1&&wmNews.getStatus()==9){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //判断是否存在关联关系
        LambdaQueryWrapper<WmNewsMaterial> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(WmNewsMaterial::getNewsId,id);
        int count = wmNewsMaterialService.count(wrapper);
        if (count>0){
            wmNewsMaterialService.remove(wrapper);
        }
        //删除
        removeById(id);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }



    @Autowired
    private KafkaTemplate kafkaTemplate;
    /**
     * 自媒体文章-发布、修改，保存草稿
     * @param
     * @return
   */
    @Override
    @Transactional
    @GlobalTransactional
    public ResponseResult submitNews(WmNewsDto dto) {

        if (dto==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        if (dto.getContent()==null||dto.getContent().length()==0){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //校验Type类型是否合法
        if (!checkType(dto.getType())){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //判断是否是草稿和提交文件，是则跳过，不是则返回
        if (!checkStatus(dto.getStatus())){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //images - 是所有的封面素材图片进行拼接的串

        List<String> contentList = getContentPicList(dto);

        List<String> list = dto.getImages();
        //如果images等于null，判断是否是自动赋值
        if (list==null||list.size()==0){
            if (dto.getType()==MediaConstans.WM_NEWS_TYPE_AUTO_PIC){  //判断是否是自动选择封面图片
                //内容图片的个数小于等于2 则为单图截图一张图，
                // 内容图片大于等于3，则为多图，截图三张图，内容中没有图片，则为无图
                list=new ArrayList<>();
                if (contentList.size()>0&&contentList.size()<=2){
                    list.add(contentList.get(0));
                }else if (contentList.size()>=3){
                    list.add(contentList.get(0));
                    list.add(contentList.get(1));
                    list.add(contentList.get(3));
                }
                dto.setImages(list);
            }else if(dto.getType()==MediaConstans.WM_NEWS_TYPE_NO_PIC){

            }else {
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
            }
        }

        //判断是修改还是保存
        if (dto.getId()!=null){
            wmNewsMaterialService.remove(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId,dto.getId()));
        }
        WmUser user = WmThreadLocalUtils.getUser();
        WmNews news = JSON.parseObject(JSON.toJSONString(dto), WmNews.class);
        news.setCreatedTime(new Date());
        news.setUserId(user.getId());
        StringBuilder sb=new StringBuilder();
        for (String s : list) {
            sb.append(s.replace(fileServerUrl,"")+",");
        }
       String ss=  sb.length()>0?sb.substring(0,sb.length()-1):null;
        news.setImages(ss);
        saveOrUpdate(news);
        //处理关系表

        //此处只能用news.getId()不能用dto.getId()，如果是第一次保存dto.getId()没有news_id
        boolean ib = saveWmNewsMaterial(Arrays.asList(news.getImages().split(",")),news.getId(),MediaConstans.WM_NEWS_MATERIAL_TYPE_MAIN);

        boolean cb = saveWmNewsMaterial(contentList,news.getId(),MediaConstans.WM_NEWS_MATERIAL_TYPE_CONTENT);
       if (ib&&cb){
           kafkaTemplate.send("autoScanByMediaNewsId",news.getId()+""); //自动审核
           return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
       }


        return ResponseResult.errorResult(AppHttpCodeEnum.FAIL);
    }


    @Autowired
    ArticleFeign articleFeign;
    @Override
    public ResponseResult downOrUp(NewsDto dto) {
       if (dto==null||dto.getId()==null||dto.getEnable()==null){
           return  ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
       }
        WmNews news = getById(dto.getId());

       //判断是否有该文章，是否已发布，只有发布的文章才可以上下架
       if (news==null||!(news.getStatus()== WmNews.Status.PUBLISHED.getCode())){
           return  ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
       }
       news.setEnable( dto.getEnable());

       updateById(news);
       articleFeign.downOrUp(dto);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 查询状态为8的所有待发布文章的id，进行定时发布
     * @param
     * @return
     */
    @Override
    public ResponseResult<List<Integer>> findAllByStatus() {

        LambdaQueryWrapper<WmNews> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(WmNews::getStatus,WmNews.Status.SUCCESS.getCode());
        wrapper.le(WmNews::getPublishTime,new Date());
        List<WmNews> newsList = list(wrapper);

        ArrayList<Integer> list=new ArrayList<>();
        for (WmNews wmNews : newsList) {
            list.add(wmNews.getId());
        }
        return ResponseResult.okResult(list);
    }

    /**
     * 添加主题图片与素材的关联关系
     * @param
     * @param id
     * @param wmNewsMaterialTypeMain
     * @return
     */
    private boolean saveWmNewsMaterial(List<String> stringList, Integer id, short wmNewsMaterialTypeMain) {
        if (stringList==null||stringList.size()==0){
            return false;
        }

        LambdaQueryWrapper<WmMaterial> wrapper=new LambdaQueryWrapper<>();
       wrapper.in(WmMaterial::getUrl,stringList);
        List<WmMaterial> wmMaterials = wmMaterialService.list(wrapper);
        if (wmMaterials==null||wmMaterials.size()==0){
            return false;
        }
        ArrayList<WmNewsMaterial> list=new ArrayList<>(); //用于保存关联关系对象，用于批量保存
        short i=0; //引用排序
        //判断主题图片的引用是否都在素材表，如果引用素材表以外的图片则引用有问题
        for (String s : stringList) {
            boolean flag=false;
            for (WmMaterial material : wmMaterials) {
                if (s.equals(material.getUrl())){
                    flag=true;
                    WmNewsMaterial newsMaterial=new WmNewsMaterial();
                    newsMaterial.setMaterialId(material.getId());
                    newsMaterial.setNewsId(id);
                    newsMaterial.setType(wmNewsMaterialTypeMain);
                    newsMaterial.setOrd(i++);
                    list.add(newsMaterial);
                    break;
                }
            }
            if (!flag){
                return false;
            }
        }
      return   wmNewsMaterialService.saveBatch(list);
    }


    private List<String> getContentPicList(WmNewsDto dto) {
        String content = dto.getContent();
        ArrayList<String> list = new ArrayList<>();
        List<Map> maps= JSON.parseArray(content, Map.class);
        for (Map map : maps) {
            if (map.get("type").equals("image")){
                String value = map.get("value").toString().replace(fileServerUrl, "");
                list.add(value);
            }
        }
        return list;
    }

    private boolean checkStatus(Short status) {
        return status.shortValue() == MediaConstans.WM_NEWS_STATUS_DRAFT ||
                status.shortValue() == MediaConstans.WM_NEWS_STATUS_SUBMIT;
    }

    /**
     * 判断传来的type是否合法
     * //这个 0 是无图  1 是单图  3 是多图  -1 是自动
     *
     * @param type
     * @return
     */
    private boolean checkType(Short type) {
        return type.shortValue() == MediaConstans.WM_NEWS_TYPE_AUTO_PIC ||
                type.shortValue() == MediaConstans.WM_NEWS_TYPE_NO_PIC ||
                type.shortValue() == MediaConstans.WM_NEWS_TYPE_ONE_PIC ||
                type.shortValue() == MediaConstans.WM_NEWS_TYPE_MANY_PIC;

    }
}
